package br.com.maven.plugins.buildinfo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;

public class JarUtils {

	public static void editFile(String jartoEdit, String entryToEdit, Map<String, String> infos, String OPEN_BANNER, String CLOSE_BANNER) {

		File tempJar = null;

		String tempName = "";
		try {
			
			tempName = jartoEdit.substring(jartoEdit.lastIndexOf("\\"));
			
			tempJar = File.createTempFile(tempName, null);
		} catch (IOException e) {
			System.err.println("Unable to create intermediate file: " + tempName);
			e.printStackTrace();
			System.exit(-2);
		}

		JarFile jar = null;

		try {
			jar = new JarFile(jartoEdit);
		} catch (IOException e) {
			System.err.println("Unable to access original file.");
			System.exit(-3);
		}

		boolean delFlag = false;

		try {

			JarOutputStream newJar = new JarOutputStream(new FileOutputStream(tempJar));

			byte buffer[] = new byte[1024];
			int bytesRead;

			try {

				Enumeration<JarEntry> entries = jar.entries();


				for(JarEntry singleEntry : Collections.list(entries)) {
				
					InputStream is = jar.getInputStream(singleEntry);
					
					JarEntry newEntry = singleEntry; // entrada para o novo jar
					if(newEntry.getName().equals(entryToEdit)) { // se for o arquivo a editar a entrada deve ser nova
						newEntry = new JarEntry(entryToEdit);
					} 
					
					newJar.putNextEntry(newEntry);
					
					while ((bytesRead = is.read(buffer)) != -1) {
						newJar.write(buffer, 0, bytesRead);	
					}
					if(newEntry.getName().equals(entryToEdit)) { // se for o arquivo a editar append content
						//append
						newJar.write("\n".getBytes());
						newJar.write(("<!-- " + OPEN_BANNER + " -->\n").getBytes());
						for(Entry<String, String> entry : infos.entrySet()) {
							newJar.write(("<!-- " + FormatUtils.format(entry.getKey(), entry.getValue()) + " -->\n").getBytes());
						}
						newJar.write(("<!-- " + CLOSE_BANNER + " -->\n").getBytes());
					}
					
					newJar.closeEntry();
				}
				delFlag = true;

			} catch (IOException ex) {
				System.err.println("Operation aborted due to : " + ex);
			} finally {
				try {
					newJar.close();
				} catch (IOException ignored) {
				}
			}

		} catch (IOException ex) {
			System.err.println("Can't access new file");
		} finally {

			try {
				jar.close();
			} catch (IOException ignored) {
			}

			if (!delFlag) {
				tempJar.delete();
			}
		}

		if (delFlag) {
			File origFile = new File(jartoEdit);
			origFile.delete();
			tempJar.renameTo(origFile);
		}

	}

	public static void addFileToJar(String jartoEdit, String entryPath, File fileToAdd) {

		File tempJar = null;

		String tempName = "";
		try {
			
			tempName = jartoEdit.substring(jartoEdit.lastIndexOf("\\"));
			
			tempJar = File.createTempFile(tempName, null);
		} catch (IOException e) {
			System.err.println("Unable to create intermediate file: " + tempName);
			e.printStackTrace();
			System.exit(-2);
		}

		JarFile jar = null;

		try {
			jar = new JarFile(jartoEdit);
		} catch (IOException e) {
			System.err.println("Unable to access original file.");
			System.exit(-3);
		}

		boolean delFlag = false;

		try {

			JarOutputStream newJar = new JarOutputStream(new FileOutputStream(tempJar));

			byte buffer[] = new byte[1024];
			int bytesRead;

			try {

				Enumeration<JarEntry> entries = jar.entries();

				for(JarEntry singleEntry : Collections.list(entries)) {
				
					InputStream is = jar.getInputStream(singleEntry);
					
					newJar.putNextEntry(singleEntry);
					
					while ((bytesRead = is.read(buffer)) != -1) {
						newJar.write(buffer, 0, bytesRead);	
					}
					
					newJar.closeEntry();
				}
				
				// add new file
				JarEntry newJarEntry = new JarEntry(entryPath);
				newJar.putNextEntry(newJarEntry);
				InputStream is = new FileInputStream(fileToAdd);
				while ((bytesRead = is.read(buffer)) != -1) {
					newJar.write(buffer, 0, bytesRead);	
				}
				newJar.closeEntry();
				
				delFlag = true;

			} catch (IOException ex) {
				System.err.println("Operation aborted due to : " + ex);
			} finally {
				try {
					newJar.close();
				} catch (IOException ignored) {
				}
			}

		} catch (IOException ex) {
			System.err.println("Can't access new file");
		} finally {

			try {
				jar.close();
			} catch (IOException ignored) {
			}

			if (!delFlag) {
				tempJar.delete();
			}
		}

		if (delFlag) {
			File origFile = new File(jartoEdit);
			origFile.delete();
			tempJar.renameTo(origFile);
		}

	}
	
	
	
}